﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing.Design;
using HML.Design;

namespace HML
{
    /// <summary>
    /// SingleAccordion节点集合
    /// </summary>
    [Editor(typeof(SingleAccordionNodeCollectionEditor), typeof(UITypeEditor))]
    public class SingleAccordionNodeCollection : IList, ICollection, IEnumerable
    {
        #region

        private ArrayList singleAccordionNodeList = new ArrayList();

        private SingleAccordion owner = null;

        #endregion

        internal SingleAccordionNodeCollection(SingleAccordion owner)
        {
            this.owner = owner;
        }

        #region IEnumerable

        public IEnumerator GetEnumerator()
        {
            SingleAccordionNode[] listArray = new SingleAccordionNode[this.singleAccordionNodeList.Count];
            for (int index = 0; index < listArray.Length; ++index)
            {
                listArray[index] = (SingleAccordionNode)this.singleAccordionNodeList[index];
            }
            return listArray.GetEnumerator();
        }

        #endregion

        #region ICollection

        public void CopyTo(Array array, int index)
        {
            for (int i = 0; i < this.Count; i++)
            {
                array.SetValue(this.singleAccordionNodeList[i], i + index);
            }
        }

        public int Count
        {
            get { return this.singleAccordionNodeList.Count; }
        }

        public bool IsSynchronized
        {
            get { return false; }
        }

        public object SyncRoot
        {
            get { return (object)this; }
        }

        #endregion

        #region IList

        /// <summary>
        /// 添加节点
        /// </summary>
        /// <param name="value">节点（类型应该为 SingleAccordionLabelNode、SingleAccordionCategoryNode、SingleAccordionContentNode）</param>
        /// <returns></returns>
        public int Add(object value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            if (!(value is SingleAccordionLabelNode || value is SingleAccordionCategoryNode || value is SingleAccordionContentNode))
            {
                throw new ArgumentException("类型应该为 SingleAccordionLabelNode、SingleAccordionCategoryNode、SingleAccordionContentNode");
            }

            return this.Add((SingleAccordionNode)value);
        }

        /// <summary>
        /// 添加节点
        /// </summary>
        /// <param name="node">（类型应该为 SingleAccordionLabelNode、SingleAccordionCategoryNode、SingleAccordionContentNode）</param>
        /// <returns></returns>
        public int Add(SingleAccordionNode node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (node.Owner != null || node.Parent != null)
            {
                throw new ArgumentException("SingleAccordionNode节点不应该同时被添加到多个地方，请先从原有地方移除再添加");
            }

            if (node is SingleAccordionCategoryNode && this.owner != null && !this.owner.Multiple && this.owner.FindExpand().Length > 0)
            {
                ((SingleAccordionCategoryNode)node).Expand = false;
            }
            node.Owner = this.owner;
            node.Parent = null;
            this.singleAccordionNodeList.Add(node);
            if (this.owner != null)
            {
                this.owner.UpdateRealityRectangle();
                this.owner.UpdateAllNodeRectangle();
                this.owner.UpdateScrollRectangle();
                this.owner.Invalidate();
            }
            return this.Count - 1;
        }

        /// <summary>
        /// 添加节点
        /// </summary>
        /// <param name="nodeArray">节点集合（类型应该为 SingleAccordionLabelNode、SingleAccordionCategoryNode、SingleAccordionContentNode）</param>
        /// <returns></returns>
        public int AddRange(SingleAccordionNode[] nodeArray)
        {
            if (nodeArray == null)
            {
                throw new ArgumentNullException("nodeArray");
            }
            for (int i = 0; i < nodeArray.Length; i++)
            {
                if (nodeArray[i] == null)
                {
                    throw new ArgumentNullException("node");
                }
                if (nodeArray[i].Owner != null || nodeArray[i].Parent != null)
                {
                    throw new ArgumentException("SingleAccordionNode节点不应该同时被添加到多个地方，请先从原有地方移除再添加");
                }
            }

            for (int i = 0; i < nodeArray.Length; i++)
            {
                if (nodeArray[i] is SingleAccordionCategoryNode && this.owner != null && !this.owner.Multiple && this.owner.FindExpand().Length > 0)
                {
                    ((SingleAccordionCategoryNode)nodeArray[i]).Expand = false;
                }
                nodeArray[i].Owner = this.owner;
                nodeArray[i].Parent = null;
                this.singleAccordionNodeList.Add(nodeArray[i]);
            }
            if (this.owner != null)
            {
                this.owner.UpdateRealityRectangle();
                this.owner.UpdateAllNodeRectangle();
                this.owner.UpdateScrollRectangle();
                this.owner.Invalidate();
            }
            return this.Count - 1;
        }

        public void Clear()
        {
            for (int i = 0; i < this.singleAccordionNodeList.Count; i++)
            {
                SingleAccordionNode node = (SingleAccordionNode)this.singleAccordionNodeList[i];
                node.Parent = null;
                node.Owner = null;
            }
            this.singleAccordionNodeList.Clear();
            if (this.owner != null)
            {
                this.owner.UpdateRealityRectangle();
                this.owner.UpdateAllNodeRectangle();
                this.owner.UpdateScrollRectangle();
                this.owner.Invalidate();
                this.owner.SelectedNode = this.owner.SelectedNode;
            }
        }

        public bool Contains(object value)
        {
            if (value == null)
                throw new ArgumentNullException("value");
            return this.IndexOf(value) != -1;
        }

        bool IList.Contains(object value)
        {
            if (value is SingleAccordionLabelNode || value is SingleAccordionCategoryNode || value is SingleAccordionContentNode)
            {
                return this.Contains(value);
            }
            return false;
        }

        public int IndexOf(object value)
        {
            if (value is SingleAccordionLabelNode || value is SingleAccordionCategoryNode || value is SingleAccordionContentNode)
            {
                return this.singleAccordionNodeList.IndexOf(value);
            }
            return -1;
        }

        /// <summary>
        /// 添加节点
        /// </summary>
        /// <param name="index">插入索引</param>
        /// <param name="value">节点（类型应该为 SingleAccordionLabelNode、SingleAccordionCategoryNode、SingleAccordionContentNode）</param>
        public void Insert(int index, object value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            if (!(value is SingleAccordionLabelNode || value is SingleAccordionCategoryNode || value is SingleAccordionContentNode))
            {
                throw new ArgumentException("类型应该为 SingleAccordionLabelNode、SingleAccordionCategoryNode、SingleAccordionContentNode");
            }

            SingleAccordionNode node = (SingleAccordionNode)value;
            if (node.Owner != null || node.Parent != null)
            {
                throw new ArgumentException("SingleAccordionNode节点不应该同时被添加到多个地方，请先从原有地方移除再添加");
            }

            if (index > this.Count)
            {
                index = this.Count;
            }
            ArrayList tmp = new ArrayList();
            for (int i = 0; i < index; i++)
            {
                tmp.Add(this.singleAccordionNodeList[i]);
            }
            if (node is SingleAccordionCategoryNode && this.owner != null && !this.owner.Multiple && this.owner.FindExpand().Length > 0)
            {
                ((SingleAccordionCategoryNode)node).Expand = false;
            }
            node.Owner = this.owner;
            node.Parent = null;
            tmp.Add(value);
            for (int i = index; i < this.Count; i++)
            {
                tmp.Add(this.singleAccordionNodeList[i]);
            }
            this.singleAccordionNodeList = tmp;

            if (this.owner != null)
            {
                this.owner.UpdateRealityRectangle();
                this.owner.UpdateAllNodeRectangle();
                this.owner.UpdateScrollRectangle();
                this.owner.Invalidate();
            }
        }

        public bool IsFixedSize
        {
            get { return false; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        /// <summary>
        /// 移除节点
        /// </summary>
        /// <param name="value">节点（类型应该为 SingleAccordionLabelNode、SingleAccordionCategoryNode、SingleAccordionContentNode）</param>
        public void Remove(object value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            if (!(value is SingleAccordionLabelNode || value is SingleAccordionCategoryNode || value is SingleAccordionContentNode))
            {
                throw new ArgumentException("类型应该为 SingleAccordionLabelNode、SingleAccordionCategoryNode、SingleAccordionContentNode");
            }

            this.Remove((SingleAccordionNode)value);
        }

        /// <summary>
        /// 移除节点
        /// </summary>
        /// <param name="node">节点（类型应该为 SingleAccordionLabelNode、SingleAccordionCategoryNode、SingleAccordionContentNode）</param>
        public void Remove(SingleAccordionNode node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            node.Owner = null;
            node.Parent = null;
            this.singleAccordionNodeList.Remove(node);
            if (this.owner != null)
            {
                this.owner.UpdateRealityRectangle();
                this.owner.UpdateAllNodeRectangle();
                this.owner.UpdateScrollRectangle();
                this.owner.Invalidate();
                this.owner.SelectedNode = this.owner.SelectedNode;
            }
        }

        public void RemoveAt(int index)
        {
            SingleAccordionNode node = (SingleAccordionNode)this.singleAccordionNodeList[index];
            node.Owner = null;
            node.Parent = null;
            this.singleAccordionNodeList.RemoveAt(index);
            if (this.owner != null)
            {
                this.owner.UpdateRealityRectangle();
                this.owner.UpdateAllNodeRectangle();
                this.owner.UpdateScrollRectangle();
                this.owner.Invalidate();
                this.owner.SelectedNode = this.owner.SelectedNode;
            }
        }

        public SingleAccordionNode this[int index]
        {
            get { return (SingleAccordionNode)this.singleAccordionNodeList[index]; }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }
                if (value.Owner != null || value.Parent != null)
                {
                    throw new ArgumentException("SingleAccordionNode节点不应该同时被添加到多个地方，请先从原有地方移除再添加");
                }

                ((SingleAccordionNode)this.singleAccordionNodeList[index]).Owner = null;
                ((SingleAccordionNode)this.singleAccordionNodeList[index]).Parent = null;
                if (value is SingleAccordionCategoryNode && this.owner != null && !this.owner.Multiple && this.owner.FindExpand().Length > 0)
                {
                    ((SingleAccordionCategoryNode)value).Expand = false;
                }
                value.Owner = this.owner;
                value.Parent = null;
                this.singleAccordionNodeList[index] = value;
                if (this.owner != null)
                {
                    this.owner.UpdateRealityRectangle();
                    this.owner.UpdateAllNodeRectangle();
                    this.owner.UpdateScrollRectangle();
                    this.owner.Invalidate();
                    this.owner.SelectedNode = this.owner.SelectedNode;
                }
            }
        }

        object IList.this[int index]
        {
            get { return (object)this.singleAccordionNodeList[index]; }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }
                if (!(value is SingleAccordionLabelNode || value is SingleAccordionCategoryNode || value is SingleAccordionContentNode))
                {
                    throw new ArgumentException("类型应该为 SingleAccordionLabelNode、SingleAccordionCategoryNode、SingleAccordionContentNode");
                }
                SingleAccordionNode node = (SingleAccordionNode)value;
                if (node.Owner != null || node.Parent != null)
                {
                    throw new ArgumentException("SingleAccordionNode节点不应该同时被添加到多个地方，请先从原有地方移除再添加");
                }

                ((SingleAccordionNode)this.singleAccordionNodeList[index]).Owner = null;
                ((SingleAccordionNode)this.singleAccordionNodeList[index]).Parent = null;
                if (value is SingleAccordionCategoryNode && this.owner != null && !this.owner.Multiple && this.owner.FindExpand().Length > 0)
                {
                    ((SingleAccordionCategoryNode)value).Expand = false;
                }
                node.Owner = this.owner;
                node.Parent = null;
                this.singleAccordionNodeList[index] = node;
                if (this.owner != null)
                {
                    this.owner.UpdateRealityRectangle();
                    this.owner.UpdateAllNodeRectangle();
                    this.owner.UpdateScrollRectangle();
                    this.owner.Invalidate();
                    this.owner.SelectedNode = this.owner.SelectedNode;
                }
            }
        }

        #endregion

    }

}
